package com.scalefuture.gmemcached;

import com.sun.grizzly.*;
import com.sun.grizzly.filter.ParserProtocolFilter;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import org.apache.commons.cli.*;

import java.net.Inet4Address;

/**
 * @author <a href="mailto:dev@scalefuture.com">Steve Tzou</a>
 */

public class GMemcached {
    public static final String STORED = "STORED\r\n";
    public static final String ERROR = "ERROR\r\n";
    public static final String CLIENT_ERROR = "CLIENT_ERROR #\r\n";
    public static final String SERVER_ERROR = "SERVER_ERROR #\r\n";
    public static final String NOT_STORED = "NOT_STORED\r\n";
    public static final String DELETED = "DELETED\r\n";
    public static final String NOT_FOUND = "NOT_FOUND\r\n";
    public static final String OK = "OK\r\n";


    public static final String NAME = "GMemcached";
    public static final String VERSION = "0.5";
    private static final int PORT = 11211;
    public static Cache map;

    public static void main(String args[]) throws Exception {
        String addr = null;
        int port = PORT;

        Options options = new Options();
        options.addOption("h", "help", false, "help infomation");
        options.addOption("p", "port", true, "port");
        options.addOption("l", "listen", true, "address");
        options.addOption("v", "version", false, "version");

        CommandLineParser parser = new PosixParser();
        CommandLine cmdline = parser.parse(options, args);

        if (cmdline.hasOption("help") || cmdline.hasOption("h")) {
            System.out.println(NAME + " Version " + VERSION);
            System.out.println("http://code.google.com/p/gmemcached\n");
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp("GMemcached.bat", options);
            return;
        }
        if (cmdline.hasOption("v") || cmdline.hasOption("version")) {
            System.out.println(NAME + " Version " + VERSION);
            return;
        }
        if (cmdline.hasOption("p")) {
            port = Integer.parseInt(cmdline.getOptionValue("p"));
        } else if (cmdline.hasOption("port")) {
            port = Integer.parseInt(cmdline.getOptionValue("port"));
        }
        if (cmdline.hasOption("l")) {
            addr = cmdline.getOptionValue("l");
        } else if (cmdline.hasOption("listen")) {
            addr = cmdline.getOptionValue("listen");
        }
        //test
        CacheManager manager = new CacheManager();
        map = new Cache("testCache", 5000, false, false, 5, 2);
        manager.addCache(map);

        Controller controller = new Controller();
        TCPSelectorHandler tcpSelector = new TCPSelectorHandler();
        if (addr != null) tcpSelector.setInet(Inet4Address.getByName(addr));
        tcpSelector.setPort(port);
        controller.addSelectorHandler(tcpSelector);

        Pipeline mySharedPipeline = new DefaultPipeline();
        mySharedPipeline.setMaxThreads(50);
        controller.setPipeline(mySharedPipeline);

        controller.setProtocolChainInstanceHandler(new DefaultProtocolChainInstanceHandler() {
            public ProtocolChain poll() {
                ProtocolChain protocolChain = protocolChains.poll();

                if (protocolChain == null) {
                    protocolChain = new DefaultProtocolChain();
                    protocolChain.addFilter(new ParserProtocolFilter() {
                        public ProtocolParser newProtocolParser() {
                            return new MemcachedProtocolParser();
                        }
                    });
                    protocolChain.addFilter(new ProcessorFilter());
                    ((DefaultProtocolChain) protocolChain).setContinuousExecution(true);
                    offer(protocolChain);
                }
                return protocolChain;
            }
        });
        controller.start();
    }
}